{% extends "base.html" %}

{% block title %}脚本编辑器{% endblock %}

{% block extra_css %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/monokai.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/foldgutter.min.css">
<style>
    .editor-container {
        height: 500px;
        border: 1px solid #ddd;
        border-radius: 5px;
    }
    
    .CodeMirror {
        height: 100%;
        font-size: 14px;
    }
    
    .output-container {
        height: 300px;
        background-color: #1e1e1e;
        color: #ffffff;
        font-family: 'Courier New', monospace;
        font-size: 12px;
        padding: 10px;
        overflow-y: auto;
        border-radius: 5px;
        white-space: pre-wrap;
    }
    
    .script-info {
        background-color: #f8f9fa;
        padding: 15px;
        border-radius: 5px;
        margin-bottom: 20px;
    }
    
    .btn-toolbar {
        margin-bottom: 15px;
    }
    
    .execution-status {
        padding: 8px 12px;
        border-radius: 4px;
        font-weight: bold;
        display: none;
    }
    
    .status-running {
        background-color: #fff3cd;
        color: #856404;
        border: 1px solid #ffeaa7;
    }
    
    .status-success {
        background-color: #d4edda;
        color: #155724;
        border: 1px solid #c3e6cb;
    }
    
    .status-error {
        background-color: #f8d7da;
        color: #721c24;
        border: 1px solid #f5c6cb;
    }
    
    .save-indicator {
        display: none;
        color: #28a745;
        font-size: 14px;
    }
    
    .unsaved-indicator {
        display: none;
        color: #dc3545;
        font-size: 14px;
    }
</style>
{% endblock %}

{% block content %}
<div class="container-fluid">
    <!-- 面包屑导航 -->
    <nav aria-label="breadcrumb" class="mb-3">
        <ol class="breadcrumb">
            <li class="breadcrumb-item"><a href="/dashboard/scripts">脚本管理</a></li>
            <li class="breadcrumb-item active" aria-current="page">脚本编辑器</li>
        </ol>
    </nav>

    <!-- 脚本信息 -->
    <div class="script-info">
        <div class="row">
            <div class="col-md-8">
                <h4 id="scriptName">加载中...</h4>
                <p class="text-muted mb-1" id="scriptDescription">-</p>
                <small class="text-muted">
                    语言: <span id="scriptLanguage">-</span> | 
                    创建时间: <span id="scriptCreatedAt">-</span> |
                    最后修改: <span id="scriptUpdatedAt">-</span>
                </small>
            </div>
            <div class="col-md-4 text-end">
                <span class="save-indicator">
                    <i class="fas fa-check-circle"></i> 已保存
                </span>
                <span class="unsaved-indicator">
                    <i class="fas fa-exclamation-circle"></i> 有未保存的更改
                </span>
            </div>
        </div>
    </div>

    <!-- 工具栏 -->
    <div class="btn-toolbar" role="toolbar">
        <div class="btn-group me-2" role="group">
            <button type="button" class="btn btn-primary" id="saveBtn">
                <i class="fas fa-save"></i> 保存
            </button>
            <button type="button" class="btn btn-success" id="runBtn">
                <i class="fas fa-play"></i> 运行测试
            </button>
            <button type="button" class="btn btn-danger" id="stopBtn" style="display: none;">
                <i class="fas fa-stop"></i> 停止执行
            </button>
        </div>

        <div class="execution-status" id="executionStatus"></div>
    </div>

    <div class="row">
        <!-- 代码编辑器 -->
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">
                    <h6 class="mb-0">代码编辑器</h6>
                </div>
                <div class="card-body p-0">
                    <div class="editor-container">
                        <textarea id="codeEditor"></textarea>
                    </div>
                </div>
            </div>
        </div>

        <!-- 执行输出 -->
        <div class="col-md-4">
            <div class="card">
                <div class="card-header d-flex justify-content-between align-items-center">
                    <h6 class="mb-0">执行输出</h6>
                    <button type="button" class="btn btn-sm btn-outline-secondary" id="clearOutputBtn">
                        <i class="fas fa-trash"></i> 清空
                    </button>
                </div>
                <div class="card-body p-0">
                    <div class="output-container" id="outputContainer">
                        点击"运行测试"按钮执行脚本...
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- 保存确认模态框 -->
<div class="modal fade" id="saveConfirmModal" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">确认保存</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                确定要保存对脚本的修改吗？
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
                <button type="button" class="btn btn-primary" id="confirmSaveBtn">确认保存</button>
            </div>
        </div>
    </div>
</div>
{% endblock %}

{% block extra_js %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/python/python.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/shell/shell.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/javascript/javascript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/foldcode.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/foldgutter.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/brace-fold.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/indent-fold.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>

<script>
let editor;
let scriptId;
let originalContent = '';
let isExecuting = false;
let socket = null;
let currentTestExecutionId = null;

// 获取脚本ID
scriptId = window.location.pathname.split('/').pop();

// 初始化WebSocket连接
function initWebSocket() {
    if (socket) {
        socket.disconnect();
    }
    
    socket = io();
    
    socket.on('connect', function() {
        console.log('WebSocket连接已建立');
    });
    
    socket.on('disconnect', function() {
        console.log('WebSocket连接已断开');
    });
    
    socket.on('script_test_output', function(data) {
        if (data.test_id === currentTestExecutionId) {
            if (data.output_type === 'stdout' && data.content) {
                appendOutput(data.content);
            } else if (data.output_type === 'stderr' && data.content) {
                appendOutput(data.content, 'error');
            } else if (data.output_type === 'status' && data.content) {
                appendOutput(data.content);
                
                // 检查是否是完成状态
                if (data.content.includes('测试执行完成') || data.content.includes('测试执行失败')) {
                    stopExecution();
                    
                    if (data.content.includes('测试执行完成')) {
                        $('#executionStatus').removeClass().addClass('execution-status status-success').text('执行成功');
                    } else {
                        $('#executionStatus').removeClass().addClass('execution-status status-error').text('执行失败');
                    }
                }
            } else if (data.output_type === 'error' && data.content) {
                appendOutput(data.content, 'error');
                stopExecution();
                $('#executionStatus').removeClass().addClass('execution-status status-error').text('执行失败');
            }
        }
    });
    
    socket.on('error', function(error) {
        console.error('WebSocket错误:', error);
        appendOutput('\nWebSocket连接错误', 'error');
    });
}

// 初始化代码编辑器
function initEditor() {
    editor = CodeMirror.fromTextArea(document.getElementById('codeEditor'), {
        lineNumbers: true,
        mode: 'python',
        theme: 'monokai',
        indentUnit: 4,
        lineWrapping: true,
        foldGutter: true,
        gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
        extraKeys: {
            "Ctrl-S": function(cm) {
                saveScript();
            }
        }
    });

    // 监听内容变化
    editor.on('change', function() {
        checkForChanges();
    });
}

// 加载脚本内容
function loadScript() {
    $.get(`/api/scripts/${scriptId}/content`)
        .done(function(response) {
            if (response.success) {
                const script = response.data.script;
                const content = response.data.content;
                
                // 更新脚本信息
                $('#scriptName').text(script.name);
                $('#scriptDescription').text('脚本文件');
                $('#scriptLanguage').text(script.language || 'Python');
                $('#scriptCreatedAt').text(new Date(script.created_at).toLocaleString('zh-CN'));
                $('#scriptUpdatedAt').text(new Date(script.updated_at).toLocaleString('zh-CN'));
                
                // 设置编辑器内容和模式
                originalContent = content || '';
                editor.setValue(originalContent);
                
                // 根据语言设置编辑器模式
                const language = (script.language || 'python').toLowerCase();
                let mode = 'python';
                if (language.includes('shell') || language.includes('bash')) {
                    mode = 'shell';
                } else if (language.includes('javascript') || language.includes('js')) {
                    mode = 'javascript';
                }
                editor.setOption('mode', mode);
                
                // 清除未保存指示器
                $('.save-indicator').show();
                $('.unsaved-indicator').hide();
            } else {
                showAlert('加载脚本失败: ' + response.message, 'danger');
            }
        })
        .fail(function(xhr, status, error) {
            showAlert('网络错误，无法加载脚本', 'danger');
            console.error('加载脚本失败:', status, error);
        });
}

// 检查内容是否有变化
function checkForChanges() {
    const currentContent = editor.getValue();
    if (currentContent !== originalContent) {
        $('.save-indicator').hide();
        $('.unsaved-indicator').show();
    } else {
        $('.save-indicator').show();
        $('.unsaved-indicator').hide();
    }
}

// 保存脚本
function saveScript() {
    const content = editor.getValue();
    
    $.ajax({
        url: `/api/scripts/${scriptId}/content`,
        type: 'PUT',
        contentType: 'application/json',
        data: JSON.stringify({ content: content }),
        dataType: 'json'
    })
    .done(function(response) {
        if (response.success) {
            originalContent = content;
            $('.save-indicator').show();
            $('.unsaved-indicator').hide();
            showAlert('脚本保存成功', 'success');
        } else {
            showAlert('保存失败: ' + response.message, 'danger');
        }
    })
    .fail(function(xhr, status, error) {
        showAlert('网络错误，保存失败', 'danger');
        console.error('保存脚本失败:', status, error);
    });
}

// 运行脚本
function runScript() {
    if (isExecuting) {
        showAlert('脚本正在执行中，请等待完成', 'warning');
        return;
    }
    
    // 检查是否有未保存的更改
    if (editor.getValue() !== originalContent) {
        if (!confirm('检测到未保存的更改，是否先保存再执行？')) {
            return;
        }
        saveScript();
        // 等待保存完成后再执行
        setTimeout(runScript, 1000);
        return;
    }
    
    isExecuting = true;
    $('#runBtn').hide();
    $('#stopBtn').show();
    $('#executionStatus').removeClass().addClass('execution-status status-running').text('正在执行...').show();
    
    // 清空输出
    $('#outputContainer').text('开始执行脚本...\n');
    
    // 确保WebSocket连接已建立
    if (!socket || !socket.connected) {
        initWebSocket();
    }
    
    // 使用POST请求启动脚本测试
    $.ajax({
        url: `/api/scripts/${scriptId}/test`,
        type: 'POST',
        contentType: 'application/json',
        dataType: 'json'
    })
    .done(function(response) {
        // 启动脚本测试成功，设置当前测试执行ID并加入WebSocket房间
        if (response.success) {
            currentTestExecutionId = response.data.test_execution_id;
            
            // 加入WebSocket房间以接收实时输出
            if (socket && socket.connected) {
                socket.emit('join', `script_test_${currentTestExecutionId}`);
                console.log(`已加入WebSocket房间: script_test_${currentTestExecutionId}`);
            }
            
            appendOutput(`脚本测试已启动，执行ID: ${currentTestExecutionId}\n`);
        } else {
            appendOutput(`启动脚本测试失败: ${response.message}\n`, 'error');
            stopExecution();
            $('#executionStatus').removeClass().addClass('execution-status status-error').text('启动失败');
        }
    })
    .fail(function(xhr, status, error) {
        appendOutput(`网络错误，启动脚本测试失败: ${status} ${error}\n`, 'error');
        stopExecution();
        $('#executionStatus').removeClass().addClass('execution-status status-error').text('网络错误');
        console.error('启动脚本测试失败:', status, error);
    });
}

// 停止执行
function stopExecution() {
    currentTestExecutionId = null;
    
    isExecuting = false;
    $('#runBtn').show();
    $('#stopBtn').hide();
    
    // 3秒后隐藏状态
    setTimeout(function() {
        $('#executionStatus').hide();
    }, 3000);
}

// 强制停止执行
function forceStopExecution() {
    $.post(`/api/scripts/${scriptId}/stop`)
        .done(function(response) {
            if (response.success) {
                appendOutput('\n执行已被用户停止');
                showAlert('执行已停止', 'info');
            }
        })
        .fail(function() {
            showAlert('停止执行失败', 'danger');
        });
    
    stopExecution();
}

// 添加输出内容
function appendOutput(content, type = 'normal') {
    const outputContainer = $('#outputContainer');
    const timestamp = new Date().toLocaleTimeString();
    
    let formattedContent = content;
    if (type === 'error') {
        formattedContent = `[${timestamp}] ${content}`;
    } else if (content.trim()) {
        formattedContent = content;
    }
    
    outputContainer.append(formattedContent + '\n');
    outputContainer.scrollTop(outputContainer[0].scrollHeight);
}

// 清空输出
function clearOutput() {
    $('#outputContainer').text('输出已清空...\n');
}





// 显示提示信息
function showAlert(message, type) {
    // 使用基础模板中定义的全局showMessage函数（即showToast）
    if (typeof window.showMessage === 'function') {
        // 映射类型到Toast支持的类型
        let toastType = type;
        switch(type) {
            case 'danger':
                toastType = 'error';
                break;
            case 'warning':
                toastType = 'warning';
                break;
            case 'success':
                toastType = 'success';
                break;
            default:
                toastType = 'info';
        }
        showMessage(message, toastType, 3000);
    } else {
        // 如果全局函数不可用，回退到原来的实现
        const alertClass = `alert-${type}`;
        const alertHtml = `
            <div class="alert ${alertClass} alert-dismissible fade show" role="alert">
                ${message}
                <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
            </div>
        `;
        
        // 移除现有的alert
        $('.alert').remove();
        
        // 添加新的alert到页面顶部
        $('body').prepend(alertHtml);
        
        // 3秒后自动消失
        setTimeout(function() {
            $('.alert').alert('close');
        }, 3000);
    }
}

// 事件绑定
$(document).ready(function() {
    initEditor();
    loadScript();
    initWebSocket();
    
    // 保存按钮
    $('#saveBtn').click(saveScript);
    
    // 运行按钮
    $('#runBtn').click(runScript);
    
    // 停止按钮
    $('#stopBtn').click(forceStopExecution);
    
    // 清空输出按钮
    $('#clearOutputBtn').click(clearOutput);
    
    // 键盘快捷键
    $(document).keydown(function(e) {
        if (e.ctrlKey && e.key === 's') {
            e.preventDefault();
            saveScript();
        }
    });
    
    // 页面离开前检查未保存的更改
    window.addEventListener('beforeunload', function(e) {
        if (editor && editor.getValue() !== originalContent) {
            e.preventDefault();
            e.returnValue = '您有未保存的更改，确定要离开吗？';
        }
    });
});
</script>
{% endblock %}